package com.uzhie.jt808.client;

import com.uzhie.jt808.util.ByteUtil;
import com.uzhie.jt808.util.JT808ProtocolUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.apache.log4j.Logger;

/**
 * Created by TangFei on 2018/8/28.
 * 接收服务端的消息
 */
@ChannelHandler.Sharable
public class InHandler extends ChannelInboundHandlerAdapter {

    private Logger logger = Logger.getLogger(getClass());

    private int flowNum = 0;

    private String sim = String.format("%012d", Thread.currentThread().getId());

    public InHandler() {
        super();
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        super.channelRegistered(ctx);
        logger.debug("InHandler channelRegistered");
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        super.channelUnregistered(ctx);
        logger.debug("InHandler channelUnregistered");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        byte[] bytes = ByteBufUtil.decodeHexDump("7e0100002d018000041509014d001f000000000000004d523938303444000000000000000000000000003431383030303001d4a54139393941418d7e");
        ByteBuf buffer = ctx.alloc().buffer();
        buffer.writeBytes(bytes);
        ctx.writeAndFlush(buffer);
        logger.debug("InHandler channelActive");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        logger.debug("InHandler channelInactive");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        logger.info("收到响应 " + ByteBufUtil.hexDump((ByteBuf) msg));
        logger.debug("InHandler channelRead");
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
        logger.debug("InHandler channelReadComplete");
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.WRITER_IDLE) {
                logger.info("发送心跳消息");
                ctx.writeAndFlush(buildMsg(0X0002, new byte[]{}, ctx));
                logger.info("发送位置信息");
                ctx.writeAndFlush(buildGPSMsg(ctx));
            }
        }
        logger.debug("InHandler userEventTriggered");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        logger.debug("InHandler exceptionCaught", cause);
    }

    private ByteBuf buildGPSMsg(ChannelHandlerContext context){
        // 7e0200004e015639932744924b00000000000c00030213106806c47a12009a000000991808221727440104000000610202000003020000040200002504000000002a0200002b04002d003d30010531010d140400000000ab020064037e
        StringBuilder stringBuilder = new StringBuilder("0200004e");
        stringBuilder.append(sim);
        stringBuilder.append("924b00000000000c00030213106806c47a12009a000000991808221727440104000000610202000003020000040200002504000000002a0200002b04002d003d30010531010d140400000000ab020064");
        byte[] bytes = ByteBufUtil.decodeHexDump(stringBuilder);
        ByteBuf buffer = context.alloc().buffer();
        buffer.writeByte(0X7E);
        buffer.writeBytes(bytes);
        buffer.writeBytes(JT808ProtocolUtil.parseInt2Byte(ByteUtil.parseCheckCode(bytes, bytes.length)));
        buffer.writeByte(0X7E);
        return buffer;
    }

    private ByteBuf buildMsg(int msgID, byte[] body, ChannelHandlerContext context) {
        ByteBuf byteBuf = context.alloc().buffer();
        byteBuf.markReaderIndex();
        byteBuf.markWriterIndex();
        byteBuf.writeBytes(JT808ProtocolUtil.parseInt2Word(msgID));
        byteBuf.writeBytes(JT808ProtocolUtil.parseInt2Word(JT808ProtocolUtil.generateMsgBodyProps(body.length, 0, false, 0)));
        byteBuf.writeBytes(ByteBufUtil.decodeHexDump(sim));
        byteBuf.writeBytes(JT808ProtocolUtil.parseInt2Word(flowNum));
        flowNum++;
        byteBuf.writeBytes(body);
        byte[] hb = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(hb);
        byte[] checkCode = JT808ProtocolUtil.parseInt2Byte(ByteUtil.parseCheckCode(hb, hb.length));
        byteBuf.resetReaderIndex();
        byteBuf.resetWriterIndex();
        byteBuf.writeByte(0X7E);
        byteBuf.writeBytes(hb);
        byteBuf.writeBytes(checkCode);
        byteBuf.writeByte(0X7E);
        return byteBuf;
    }
}
